package algorithm_demo.sort;

import java.util.Arrays;

/**
 * 冒泡排序
 * <p>
 * 冒泡排序是一种简单的排序算法。它重复地遍历要排序的序列，依次比较两个元素，
 * 如果它们的顺序错误就把它们交换过来。遍历序列的工作是重复地进行直到没有再需要交换为止，
 * 此时说明该序列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢 “浮” 到数列的顶端。
 * <p>
 * <p>
 * 算法步骤比较相邻的元素。如果第一个比第二个大，就交换它们两个；对每一对相邻元素作同样的工作，
 * 从开始第一对到结尾的最后一对，这样在最后的元素应该会是最大的数；针对所有的元素重复以上的步骤，
 * 除了最后一个；重复步骤 1~3，直到排序完成。# 图解算法
 * <p>
 * <p>
 * 算法步骤比较相邻的元素。如果第一个比第二个大，就交换它们两个；
 * 对每一对相邻元素作同样的工作，从开始第一对到结尾的最后一对，这样在最后的元素应该会是最大的数；
 * 针对所有的元素重复以上的步骤，除了最后一个；
 * 重复步骤 1~3，直到排序完成。
 * <p>
 * 算法分析
 * 稳定性：稳定
 * 时间复杂度 ：最佳：O(n) ，最差：O(n2)， 平均：O(n2)
 * 空间复杂度 ：O(1)
 * 排序方式 ：In-place
 *
 * @author Api
 * @date 2022/11/18 21:30
 */
public class BubbleSort {

    public static void main(String[] args) {
        int[] arr = {0, 22, 34, 1, 3, 2, 12, 12, 3, 4, 54, 53};
        int[] ints = bubbleSort(arr);
        System.out.println(Arrays.toString(ints));
        bubbleSort1(arr);
        System.out.println(Arrays.toString(arr));
    }

    /*此处对代码做了一个小优化，加入了 is_sorted Flag，目的是将算法的最佳时间复杂度优化为 O(n)，
    即当原输入序列就是排序好的情况下，该算法的时间复杂度就是 O(n)。*/
    public static int[] bubbleSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            boolean flag = true;
            for (int j = 0; j < arr.length - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                    flag = false;
                }
            }
            if (flag) {
                break;
            }
        }
        return arr;
    }


    //左神
    public static void bubbleSort1(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        for (int e = arr.length - 1; e > 0; e--) {
            for (int i = 0; i < e; i++) {
                if (arr[i] > arr[i + 1]) {
                    swap(arr, i, i+1);
                }
            }
        }

    }
    public static void swap(int[] arr, int i, int j) {
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }
}
